/*
 * Copyright 2011-2021 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0.
 * See `LICENSE` in the project root for license information.
 */

package me.ijleex.mgmt.system.role.service.impl;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.google.common.base.Strings;

import me.ijleex.mgmt.commons.util.MathUtils;
import me.ijleex.mgmt.framework.constant.Constants;
import me.ijleex.mgmt.framework.entity.Result;
import me.ijleex.mgmt.system.role.entity.Role;
import me.ijleex.mgmt.system.role.entity.RoleMenu;
import me.ijleex.mgmt.system.role.mapper.RoleMapper;
import me.ijleex.mgmt.system.role.mapper.RoleMenuMapper;
import me.ijleex.mgmt.system.role.service.IRoleMenuService;

/**
 * 角色&菜单关系 服务层实现
 *
 * @author liym
 * @since 2019-03-14 12:28:23 By 'codegen'
 */
@Service
public class RoleMenuServiceImpl implements IRoleMenuService {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    private final RoleMenuMapper mapper;
    private final RoleMapper roleMapper;

    public RoleMenuServiceImpl(RoleMenuMapper mapper, RoleMapper roleMapper) {
        this.mapper = mapper;
        this.roleMapper = roleMapper;
    }

    @Override
    public List<Long> getMenuIdByRoleId(Long roleId) {
        return this.mapper.selectMenuIdByRoleId(roleId);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result grant(RoleMenu object) {
        Long roleId = object.getRoleId();
        if (MathUtils.isNullOrZero(roleId)) {
            return Result.invalidArg("角色ID不能为空：roleId");
        }
        this.logger.debug("为角色【{}】分配菜单", roleId);

        Role role = this.roleMapper.selectById(roleId);
        if (role == null) {
            return Result.error("角色不存在：" + roleId);
        }

        String menuIds = object.getMenuIds();
        if (Strings.isNullOrEmpty(menuIds)) {
            // 如果菜单id为空，则删除已分配的菜单

            this.logger.warn("为角色分配菜单时，待分配的菜单为空，则删除角色已有的菜单");

            int x = this.mapper.deleteByRoleId(roleId);
            if (x == 0) {
                return Result.error("删除角色已有的菜单失败：" + roleId);
            } else {
                // TODO 清除缓存
                return Result.ok(roleId);
            }
        } else {
            this.logger.debug("为角色分配菜单，先删除角色原有的菜单");

            // 授权之前，删除以前授权的数据
            this.mapper.deleteByRoleId(roleId);

            String[] menuIdArr = menuIds.split(Constants.DELIMITER);
            try {
                int count = 0;
                for (String menuId : menuIdArr) {
                    object.setMenuId(Long.parseLong(menuId));
                    // 设置 remarks 的值为角色名称，方便删除时使用
                    object.setRemarks(role.getName());
                    count += this.mapper.insert(object);
                }
                return Result.ok("为角色分配菜单成功：" + roleId + "，菜单个数：" + count);
            } catch (Exception e) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                this.logger.error("为角色分配菜单失败", e);
                return Result.error("角色授权失败");
            }
        }
    }

}
